package tbs.framework.utils;

import java.util.*;

/**
 * 集合工具类
 *
 * @author abstergo
 */
public class CollUtils {
    /**
     * 检查集合是否为空
     *
     * @param collection 要检查的集合
     * @return 如果集合为null或空，则返回true；否则返回false
     */
    public static <T> boolean isEmpty(Collection<T> collection) {
        return collection == null || collection.isEmpty();
    }

    /**
     * 检查集合是否不为空
     *
     * @param collection 要检查的集合
     * @return 如果集合不为null且不为空，则返回true；否则返回false
     */
    public static <T> boolean isNotEmpty(Collection<T> collection) {
        return !isEmpty(collection);
    }

    /**
     * 检查数组是否为空
     *
     * @param array 要检查的数组
     * @return 如果数组为null或长度为0，则返回true；否则返回false
     */
    public static <T> boolean isEmpty(T[] array) {
        return array == null || array.length == 0;
    }

    /**
     * 检查数组是否不为空
     *
     * @param array 要检查的数组
     * @return 如果数组不为null且长度不为0，则返回true；否则返回false
     */
    public static <T> boolean isNotEmpty(T[] array) {
        return !isEmpty(array);
    }

    /**
     * 检查映射是否为空
     *
     * @param map 要检查的映射
     * @return 如果映射为null或空，则返回true；否则返回false
     */
    public static boolean isEmpty(Map map) {
        return map == null || map.isEmpty();
    }

    /**
     * 检查映射是否不为空
     *
     * @param map 要检查的映射
     * @return 如果映射不为null且不为空，则返回true；否则返回false
     */
    public static boolean isNotEmpty(Map map) {
        return !isEmpty(map);
    }

    /**
     * 从Iterator中获取第一个元素 如果Iterator为空或没有下一个元素，则返回null 此方法避免了对null的直接检查，使代码更加简洁
     *
     * @param iterator Iterator对象，可能为null
     * @param <T>      元素类型
     * @return 第一个元素，如果不存在则返回null
     */
    public static <T> T first(Iterator<T> iterator) {
        if (iterator == null) {
            return null;
        }
        if (iterator.hasNext()) {
            return iterator.next();
        }
        return null;
    }

    /**
     * 从Iterable中获取第一个元素 如果Iterable为空或其迭代器没有下一个元素，则返回null 此方法避免了对null的直接检查，使代码更加简洁
     *
     * @param iterable Iterable对象，可能为null
     * @param <T>      元素类型
     * @return 第一个元素，如果不存在则返回null
     */
    public static <T> T first(Iterable<T> iterable) {
        if (iterable == null) {
            return null;
        }
        Iterator<T> iterator = iterable.iterator();
        if (iterator.hasNext()) {
            return iterator.next();
        }
        return null;
    }

    /**
     * 从Collection中获取第一个元素 如果Collection为空或其迭代器没有下一个元素，则返回null 此方法利用了泛型方法的重载，避免了代码重复
     *
     * @param collection Collection对象，可能为null
     * @param <T>        元素类型
     * @return 第一个元素，如果不存在则返回null
     */
    public static <T> T first(Collection<T> collection) {
        if (CollUtils.isEmpty(collection)) {
            return null;
        }
        return first(collection.iterator());
    }

    /**
     * 从数组中获取第一个元素 如果数组为空，则返回null 此方法避免了对null的直接检查，使代码更加简洁
     *
     * @param array 数组对象，可能为null
     * @param <T>   元素类型
     * @return 第一个元素，如果不存在则返回null
     */
    public static <T> T first(T[] array) {
        if (CollUtils.isEmpty(array)) {
            return null;
        }
        return array[0];
    }

    /**
     * 获取数组中的最后一个元素 如果数组为空，则返回null 此方法适用于任何类型的数组
     *
     * @param array 数组，可以是任何类型
     * @return 数组的最后一个元素，如果数组为空则返回null
     */
    public static <T> T last(T[] array) {
        if (CollUtils.isEmpty(array)) {
            return null;
        }
        return array[array.length - 1];
    }

    /**
     * 获取集合中的最后一个元素 如果集合为空，则返回null 此方法适用于任何类型的List集合
     *
     * @param collection List集合，可以是任何类型
     * @return 集合的最后一个元素，如果集合为空则返回null
     */
    public static <T> T last(List<T> collection) {
        if (CollUtils.isEmpty(collection)) {
            return null;
        }
        return collection.get(collection.size() - 1);
    }

    /**
     * 将数组转换为只读列表 生成的列表不能进行添加、删除或修改操作 此方法适用于任何类型的数组
     *
     * @param array 数组，可以是任何类型
     * @return 包含数组元素的只读列表
     */
    public static <T> List<T> toReadOnlyList(T... array) {
        return Arrays.asList(array);
    }

    /**
     * 将数组转换为可写列表 生成的列表可以进行添加、删除或修改操作 此方法适用于任何类型的数组
     *
     * @param array 数组，可以是任何类型
     * @return 包含数组元素的可写列表
     */
    public static <T> List<T> toWritableList(T... array) {
        if (isEmpty(array)) {
            return new ArrayList<>();
        }
        List<T> list = new ArrayList<>(array.length);
        for (T t : array) {
            list.add(t);
        }
        return list;
    }

}
